home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 June: Reference Library / Dev.CD Jun 96 RL / Dev.CD Jun 96 RL.toast / Technical Documentation / develop / develop Issue 24 / develop Issue 24 code / Scriptable Database 1.0a15 / Scripting / CoreSuite.cp < prev    next >
Encoding:
Text File  |  1996-02-19  |  29.0 KB  |  841 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        CoreSuite.c
  3.  
  4.     Contains:    Event handlers for the core suite
  5.  
  6.     Written by:    Greg Anderson
  7.  
  8.     Copyright:    © 1993-1995 by Greg Anderson, all rights reserved.
  9.  
  10.         <29>     6/23/95    ga    
  11. */
  12.  
  13.  
  14.  
  15. #include "CoreSuite.h"
  16. #include "TransactionSuite.h"
  17. #include "AbstractScriptableObject.h"
  18. #include "MoreAEM.h"
  19. #include "ScriptErrors.h"
  20. #include "EventHandlerTable.h"
  21.  
  22. #include <AERegistry.h>
  23. #include <ASRegistry.h>
  24.  
  25. #include "Exceptions.h"
  26.  
  27.  
  28. #define keyAEUsing 'usin'
  29.  
  30.  
  31. #if 0
  32.  
  33. #if GENERATINGCFM
  34.     static RoutineDescriptor gExistsHandlerRD            = BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, TCoreSuite::DoExists);
  35.     static RoutineDescriptor gGetDataHandlerRD            = BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, TCoreSuite::DoGetData);
  36.     static RoutineDescriptor gSetDataHandlerRD            = BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, TCoreSuite::DoSetData);
  37.     static RoutineDescriptor gGetDataSizeHandlerRD        = BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, TCoreSuite::DoGetDataSize);
  38.     static RoutineDescriptor gNewElementHandlerRD        = BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, TCoreSuite::DoNewElement);
  39.     static RoutineDescriptor gNumberOfElementsHandlerRD    = BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, TCoreSuite::DoNumberOfElements);
  40.     static RoutineDescriptor gOpenHandlerRD                = BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, TCoreSuite::DoOpen);
  41.     static RoutineDescriptor gMoveHandlerRD                = BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, TCoreSuite::DoMove);
  42.  
  43.     AEEventHandlerUPP gCommandHandlerUPP = nil;
  44. #endif
  45.  
  46. #endif
  47.  
  48. //----------------------------------------------------------------------------------------
  49. // TCoreSuite::InstallAEHandlers: 
  50. //----------------------------------------------------------------------------------------
  51. void TCoreSuite::InstallAEHandlers(TEventHandlerTable& eventTable)
  52.     {
  53.     //
  54.     // The event handler table will generate a UPP if it needs to
  55.     //
  56.     FailErr(eventTable.InstallHandler(kCoreEventClass, 'open', (EventHandlerProcPtr) &TCoreSuite::DoOpen, kAEOpen));
  57.     FailErr(eventTable.InstallHandler(kCoreEventClass, kAEOpen, (EventHandlerProcPtr) &TCoreSuite::DoOpen, kAEOpen));
  58.     FailErr(eventTable.InstallHandler(kCoreEventClass, kAEPrint, (EventHandlerProcPtr) &TCoreSuite::DoCommand, kAEPrint));
  59.             
  60.     // events from the core suite
  61.     
  62.     FailErr(eventTable.InstallHandler(kAECoreSuite, kAEDoObjectsExist, (EventHandlerProcPtr) &TCoreSuite::DoExists, 0));
  63.     FailErr(eventTable.InstallHandler(kAECoreSuite, kAEGetData, (EventHandlerProcPtr) &TCoreSuite::DoGetData, 0));
  64.     FailErr(eventTable.InstallHandler(kAECoreSuite, kAESetData, (EventHandlerProcPtr) &TCoreSuite::DoSetData, 0));
  65.     FailErr(eventTable.InstallHandler(kAECoreSuite, kAEGetDataSize, (EventHandlerProcPtr) &TCoreSuite::DoGetDataSize, 0));
  66.     FailErr(eventTable.InstallHandler(kAECoreSuite, kAECreateElement, (EventHandlerProcPtr) &TCoreSuite::DoNewElement, 0));
  67.     FailErr(eventTable.InstallHandler(kAECoreSuite, kAECountElements, (EventHandlerProcPtr) &TCoreSuite::DoNumberOfElements, 0));
  68.  
  69.     FailErr(eventTable.InstallHandler(kAECoreSuite, kAEClone, (EventHandlerProcPtr) &TCoreSuite::DoMove, kAEClone));
  70.     FailErr(eventTable.InstallHandler(kAECoreSuite, kAEDelete, (EventHandlerProcPtr) &TCoreSuite::DoCommand, kAEDelete));
  71.     FailErr(eventTable.InstallHandler(kAECoreSuite, kAEClose, (EventHandlerProcPtr) &TCoreSuite::DoCommand, kAEClose));
  72.     FailErr(eventTable.InstallHandler(kAECoreSuite, kAEMove, (EventHandlerProcPtr) &TCoreSuite::DoMove, kAEMove));
  73.     FailErr(eventTable.InstallHandler(kAECoreSuite, kAESave, (EventHandlerProcPtr) &TCoreSuite::DoCommand, kAESave));
  74.  
  75. #if 0
  76.  
  77. #if GENERATINGCFM
  78.     // events from the required suite
  79.  
  80.     gCommandHandlerUPP    = NewRoutineDescriptor((ProcPtr) &TCoreSuite::DoCommand, uppAEEventHandlerProcInfo, GetCurrentISA());
  81.     FailNil(gCommandHandlerUPP);
  82.     
  83.     //
  84.     // kAEOpen is 'odoc', but we also have an 'open' event in the required suite due to
  85.     // Finder 7.0 oddities (not needed in the Scriptable Database, but...)
  86.     //
  87.     FailErr(AEInstallEventHandler(kCoreEventClass, 'open', &gOpenHandlerRD, kAEOpen, false));
  88.     FailErr(AEInstallEventHandler(kCoreEventClass, kAEOpen, &gOpenHandlerRD, kAEOpen, false));
  89.     FailErr(AEInstallEventHandler(kCoreEventClass, kAEPrint, gCommandHandlerUPP, kAEPrint, false));
  90.             
  91.     // events from the core suite
  92.     
  93.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEDoObjectsExist, &gExistsHandlerRD, 0, false));
  94.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEGetData, &gGetDataHandlerRD, 0, false));
  95.     FailErr(AEInstallEventHandler(kAECoreSuite, kAESetData, &gSetDataHandlerRD, 0, false));
  96.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEGetDataSize, &gGetDataSizeHandlerRD, 0, false));
  97.     FailErr(AEInstallEventHandler(kAECoreSuite, kAECreateElement, &gNewElementHandlerRD, 0, false));
  98.     FailErr(AEInstallEventHandler(kAECoreSuite, kAECountElements, &gNumberOfElementsHandlerRD, 0, false));
  99.  
  100.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEClone, &gMoveHandlerRD, kAEClone, false));
  101.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEDelete, gCommandHandlerUPP, kAEDelete, false));
  102.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEClose, gCommandHandlerUPP, kAEClose, false));
  103.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEMove, &gMoveHandlerRD, kAEMove, false));
  104.     FailErr(AEInstallEventHandler(kAECoreSuite, kAESave, &gCommandHandlerUPP, kAESave, false));
  105.  
  106.  
  107. #else
  108.     // events from the required suite
  109.     
  110.     FailErr(AEInstallEventHandler(kCoreEventClass, 'open', (AEEventHandlerProcPtr) &TCoreSuite::DoOpen, kAEOpen, false));
  111.     FailErr(AEInstallEventHandler(kCoreEventClass, kAEOpen, (AEEventHandlerProcPtr) &TCoreSuite::DoOpen, kAEOpen, false));
  112.     FailErr(AEInstallEventHandler(kCoreEventClass, kAEPrint, (AEEventHandlerProcPtr) &TCoreSuite::DoCommand, kAEPrint, false));
  113.             
  114.     // events from the core suite
  115.     
  116.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEDoObjectsExist, (AEEventHandlerProcPtr) &TCoreSuite::DoExists, 0, false));
  117.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEGetData, (AEEventHandlerProcPtr) &TCoreSuite::DoGetData, 0, false));
  118.     FailErr(AEInstallEventHandler(kAECoreSuite, kAESetData, (AEEventHandlerProcPtr) &TCoreSuite::DoSetData, 0, false));
  119.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEGetDataSize, (AEEventHandlerProcPtr) &TCoreSuite::DoGetDataSize, 0, false));
  120.     FailErr(AEInstallEventHandler(kAECoreSuite, kAECreateElement, (AEEventHandlerProcPtr) &TCoreSuite::DoNewElement, 0, false));
  121.     FailErr(AEInstallEventHandler(kAECoreSuite, kAECountElements, (AEEventHandlerProcPtr) &TCoreSuite::DoNumberOfElements, 0, false));
  122.  
  123.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEClone, (AEEventHandlerProcPtr) &TCoreSuite::DoMove, kAEClone, false));
  124.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEDelete, (AEEventHandlerProcPtr) &TCoreSuite::DoCommand, kAEDelete, false));
  125.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEClose, (AEEventHandlerProcPtr) &TCoreSuite::DoCommand, kAEClose, false));
  126.     FailErr(AEInstallEventHandler(kAECoreSuite, kAEMove, (AEEventHandlerProcPtr) &TCoreSuite::DoMove, kAEMove, false));
  127.     FailErr(AEInstallEventHandler(kAECoreSuite, kAESave, (AEEventHandlerProcPtr) &TCoreSuite::DoCommand, kAESave, false));
  128. #endif
  129.  
  130. #endif
  131.  
  132.     } // TCoreSuite::InstallAEHandlers 
  133.  
  134. //----------------------------------------------------------------------------------------
  135. // TCoreSuite::DoExists: 
  136. //----------------------------------------------------------------------------------------
  137. pascal OSErr TCoreSuite::DoExists(TAEvent& ae, TAEvent& reply, long /* refCon */)
  138.     {
  139.     Boolean directObjectExists = true;
  140.     OSErr err = noErr;
  141.  
  142.     TDescriptor objectSpecifierList;        
  143.     TTokenDescriptor directObjectToken;
  144.     TDescriptor doesExist;
  145.     TDescriptor offendingObject;
  146.     TAETransaction transaction(ae, reply);
  147.     NOREGISTER(transaction);
  148.         
  149.     Try
  150.         {
  151.         TTransactionSuite::BeginEventTransaction(transaction, kTransactionNotRequired);
  152.  
  153.         //
  154.         // Try to resolve the direct object; if there is no direct object,
  155.         // or if the direct object fails to resolve to a token, then 'exists'
  156.         // will return 'false'
  157.         //
  158.         objectSpecifierList = ae.GetDescriptorParameter(keyDirectObject);        
  159.         directObjectToken = objectSpecifierList.Resolve(transaction, &offendingObject);
  160.         
  161.         //
  162.         // Check to see if the resolved token really does exist
  163.         //
  164.         TAbstractScriptableObject* token = directObjectToken.TokenObject();
  165.             {
  166.             //
  167.             // If the token claims that it does not exist, then
  168.             // return false.  Examples where this is true includes
  169.             // the selection, which will always resolve to a token,
  170.             // but would rather return 'false' in response to an
  171.             // 'Exists' routine if there are no items in the selection.
  172.             //
  173.             if(token->Exists(transaction) == false)
  174.                 directObjectExists = false;
  175.             }
  176.         TTransactionSuite::EndEventTransaction(transaction);
  177.         }
  178.     Catch(err)
  179.         {
  180.         TTransactionSuite::TerminateEventTransaction(transaction);
  181.         directObjectExists = false;
  182.         if(err == errAENoSuchObject)
  183.             err = noErr;
  184.         else
  185.             ProcessError(err, offendingObject, reply);
  186.         }
  187.         
  188.     doesExist.SetBooleanData(directObjectExists);
  189.     reply.PutResult(doesExist);
  190.     
  191.     doesExist.Dispose();
  192.     directObjectToken.DisposeToken();
  193.     objectSpecifierList.Dispose();
  194.     offendingObject.Dispose();
  195.     
  196.     return err;
  197.     } // TCoreSuite::DoExists 
  198.  
  199. //----------------------------------------------------------------------------------------
  200. // TCoreSuite::DoGetData: 
  201. //----------------------------------------------------------------------------------------
  202. pascal OSErr TCoreSuite::DoGetData(TAEvent& ae, TAEvent& reply, long /* refCon */)
  203.     {
  204.     OSErr err = noErr;
  205.  
  206.     TDescriptor objectSpecifierList;        
  207.     TTokenDescriptor directObjectToken;
  208.     TDescriptor requestedType;
  209.     TDescriptor resultDescriptor;
  210.     TDescriptor offendingObject;
  211.     TAETransaction transaction(ae, reply);
  212.     NOREGISTER(transaction);
  213.         
  214.     Try
  215.         {
  216.         TTransactionSuite::BeginEventTransaction(transaction, kTransactionNotRequired);
  217.         objectSpecifierList = ae.GetDescriptorParameter(keyDirectObject);        
  218.         directObjectToken = objectSpecifierList.Resolve(transaction, &offendingObject);
  219.         
  220.         requestedType = ae.GetOptionalParameter(keyAERequestedType,typeAEList);
  221.                 
  222.         TAbstractScriptableObject* token = directObjectToken.TokenObject();
  223.         resultDescriptor = token->GetDataGivenListOfTypes(transaction, pContents, requestedType);
  224.         TTransactionSuite::EndEventTransaction(transaction);
  225.         reply.PutResult(resultDescriptor);
  226.         }
  227.     Catch(err)
  228.         {
  229.         TTransactionSuite::TerminateEventTransaction(transaction);
  230.         ProcessError(err, offendingObject, reply);
  231.         }
  232.  
  233.     requestedType.Dispose();
  234.     resultDescriptor.Dispose();
  235.     directObjectToken.DisposeToken();
  236.     objectSpecifierList.Dispose();
  237.     offendingObject.Dispose();
  238.     
  239.     return err;
  240.     } // TCoreSuite::DoGetData 
  241.  
  242. //----------------------------------------------------------------------------------------
  243. // TCoreSuite::DoSetData: 
  244. //----------------------------------------------------------------------------------------
  245. pascal OSErr TCoreSuite::DoSetData(TAEvent& ae, TAEvent& reply, long /* refCon */)
  246.     {
  247.     OSErr err = noErr;
  248.     
  249.     TDescriptor objectSpecifierList;
  250.     TTokenDescriptor directObjectToken;
  251.     TDescriptor keyData;
  252.     TDescriptor offendingObject;
  253.     
  254.     TAETransaction transaction(ae, reply);
  255.     NOREGISTER(transaction);
  256.         
  257.     Try
  258.         {
  259.         TTransactionSuite::BeginEventTransaction(transaction);
  260.  
  261.         objectSpecifierList = ae.GetDescriptorParameter(keyDirectObject);
  262.         directObjectToken = objectSpecifierList.Resolve(transaction, &offendingObject);
  263.                 
  264.         keyData = ae.GetDescriptorParameter(keyAEData);
  265.                 
  266.         TAbstractScriptableObject* token = directObjectToken.TokenObject();
  267.             {
  268.             TDescriptor resolvedData;
  269.             
  270.             //
  271.             // It is legal to provide an object specifier to some
  272.             // object as the key data of a SetData command.
  273.             // ResolveKeyData attempts to resolve the object specifier
  274.             // in the key data, and get the best data type from it
  275.             //
  276.             resolvedData = token->ResolveKeyData(transaction, keyData);
  277.             
  278.             //
  279.             // Often, ResolveKeyData does not need to do anything.
  280.             // To avoid requiring it to copy the key data, our
  281.             // convention is that if ResolveKeyData returns typeNull,
  282.             // then we use the original keyData.  Otherwise, we
  283.             // use the result of ResolveKeyData.
  284.             //
  285.             if(resolvedData.IsNullDescriptor())
  286.                 token->SetData(transaction, keyData);
  287.             else
  288.                 {
  289.                 //
  290.                 // Intense voodoo magic:  If we converted an object specifier
  291.                 // into an enumeration but set data did not work, then we'll
  292.                 // try a little bit harder to make it work right the second time.
  293.                 // We assume that the translation from object specifier to enumeration
  294.                 // was in error (else set data would have worked); ergo, we should
  295.                 // try to resolve the object specifier, call get data on the
  296.                 // resulting token, and pass the result to set data.
  297.                 //
  298.                 // Only do this if the best type of the token is typeEnumeration,
  299.                 // because that is the only instance in which an object specifier
  300.                 // should be translated into an enumeration.
  301.                 //
  302.                 // See the comments in TAbstractScriptableObject::ResolveKeyData
  303.                 // for related reading.
  304.                 //
  305.                 Boolean recoverAndTryAgain = (keyData.DescriptorType() == typeObjectSpecifier) && (resolvedData.DescriptorType() == typeEnumeration) && (token->BestType(transaction, pContents) == typeEnumeration);
  306.                 Try
  307.                     {
  308.                     token->SetData(transaction, resolvedData);
  309.                     recoverAndTryAgain = false;
  310.                     }
  311.                 Catch(err)
  312.                     {
  313.                     }
  314.                 
  315.                 if(recoverAndTryAgain)
  316.                     {
  317.                     resolvedData.Dispose();
  318.                     resolvedData = token->ResolveSpecifierAndGetData(transaction, keyData);
  319.                     token->SetData(transaction, resolvedData);                    
  320.                     }
  321.                 }
  322.             
  323.             resolvedData.Dispose();
  324.             }
  325.             
  326.         TTransactionSuite::EndEventTransaction(transaction);
  327.         }
  328.     Catch(err)
  329.         {
  330.         TTransactionSuite::TerminateEventTransaction(transaction);
  331.         ProcessError(err, offendingObject, reply);
  332.         }
  333.     
  334.     keyData.Dispose();
  335.     directObjectToken.DisposeToken();
  336.     objectSpecifierList.Dispose();
  337.     offendingObject.Dispose();
  338.     
  339.     return err;
  340.     } // TCoreSuite::DoSetData 
  341.  
  342. //----------------------------------------------------------------------------------------
  343. // TCoreSuite::DoGetDataSize: 
  344. //----------------------------------------------------------------------------------------
  345. pascal OSErr TCoreSuite::DoGetDataSize(TAEvent& ae, TAEvent& reply, long /* refCon */)
  346.     {
  347.     OSErr err = noErr;
  348.  
  349.     TDescriptor objectSpecifierList;        
  350.     TTokenDescriptor directObjectToken;
  351.     TDescriptor requestedType;
  352.     TDescriptor resultList;
  353.     TDescriptor offendingObject;
  354.     long resultInteger;
  355.     TAETransaction transaction(ae, reply);
  356.     NOREGISTER(transaction);
  357.     
  358.     Try
  359.         {
  360.         TTransactionSuite::BeginEventTransaction(transaction, kTransactionNotRequired);
  361.         objectSpecifierList = ae.GetDescriptorParameter(keyDirectObject);        
  362.         directObjectToken = objectSpecifierList.Resolve(transaction, &offendingObject);
  363.                         
  364.         requestedType = ae.GetOptionalParameter(keyAERequestedType,typeAEList);
  365.                 
  366.         TAbstractScriptableObject* token = directObjectToken.TokenObject();
  367.         
  368.         resultInteger = token->GetDataSizeGivenListOfTypes(transaction, pContents, requestedType);
  369.         resultList.SetSInt32Data(resultInteger);
  370.         TTransactionSuite::EndEventTransaction(transaction);
  371.         reply.PutResult(resultList);
  372.         }
  373.     Catch(err)
  374.         {
  375.         TTransactionSuite::TerminateEventTransaction(transaction);
  376.         ProcessError(err, offendingObject, reply);
  377.         }
  378.  
  379.     requestedType.Dispose();
  380.     resultList.Dispose();
  381.     directObjectToken.DisposeToken();
  382.     objectSpecifierList.Dispose();
  383.     offendingObject.Dispose();
  384.  
  385.     return err;
  386.     } // TCoreSuite::DoGetDataSize 
  387.  
  388. //----------------------------------------------------------------------------------------
  389. // TCoreSuite::DoNewElement: 
  390. //----------------------------------------------------------------------------------------
  391. pascal OSErr TCoreSuite::DoNewElement(TAEvent& ae, TAEvent& reply, long /* refCon */)
  392.     {
  393.     OSErr err = noErr;
  394.  
  395.     TDescriptor insertionLocation;
  396.     TTokenDescriptor insertHereToken;
  397.     TDescriptor initialData;
  398.     TDescriptor initialProperties;
  399.     TDescriptor resultList;
  400.     TDescriptor offendingObject;
  401.     
  402.     TAETransaction transaction(ae, reply);
  403.     NOREGISTER(transaction);
  404.         
  405.     Try
  406.         {
  407.         TTransactionSuite::BeginEventTransaction(transaction);;
  408.         DescType newObjectClass;
  409.         
  410.         newObjectClass = ae.GetDescTypeParameter(keyAEObjectClass);
  411.         insertionLocation = ae.GetOptionalParameter(keyAEInsertHere);
  412.         initialData = ae.GetOptionalParameter(keyASPrepositionTo);
  413.         if(initialData.IsNullDescriptor())
  414.             initialData = ae.GetOptionalParameter(keyAEData);
  415.         initialProperties = ae.GetOptionalParameter(keyAEPropData);
  416.                 
  417.         //
  418.         // Resolve the insertion location parameter
  419.         //
  420.         insertHereToken = insertionLocation.Resolve(transaction, &offendingObject);
  421.  
  422.         TAbstractScriptableObject* token = insertHereToken.TokenObject();
  423.         TAbstractScriptableObject* oneResult = nil;
  424.  
  425.         Boolean usedInitialData = false;
  426.         Boolean usedInitialProperties = false;
  427.                 
  428.         //
  429.         // Give the token the new object class and its initial data
  430.         //
  431.         oneResult = token->CreateNewElement(transaction, newObjectClass, initialData, initialProperties, usedInitialData, usedInitialProperties);
  432.         
  433.         //
  434.         // We don't expect 'oneResult' to ever come back nil;
  435.         // if the object couldn't be created, then 'CreateNewElement'
  436.         // should fail.
  437.         //
  438.         if(oneResult == nil)
  439.             FailErr(errAEEventFailed);
  440.  
  441.         //
  442.         // If create really did create something, then
  443.         // we would like to set its initial properties
  444.         // and return a result object specifier to the object
  445.         // If initial properties were specified, then set them here
  446.         //
  447.         if((usedInitialProperties == false) && (initialProperties.DescriptorType() != typeNull))
  448.             {
  449.             oneResult->SetProperties(transaction, initialProperties);
  450.             }
  451.         
  452.         //
  453.         // If initial data was specified, then set it
  454.         //
  455.         if((usedInitialData == false) && (initialData.DescriptorType() != typeNull))
  456.             {
  457.             oneResult->SetData(transaction, initialData);
  458.             }
  459.         
  460.         //
  461.         // Make an object specifier for the token and add it to
  462.         // the result list
  463.         //
  464.         resultList = oneResult->BuildObjectSpecifier(transaction);                        
  465. //        oneResult->DisposeDesignator();
  466.  
  467.         TTransactionSuite::EndEventTransaction(transaction);
  468.         
  469.         //
  470.         // Once all of the items are created and initialized, put the
  471.         // result list into the reply.
  472.         //
  473.         reply.PutResult(resultList);
  474.         }
  475.     Catch(err)
  476.         {
  477.         TTransactionSuite::TerminateEventTransaction(transaction);
  478.         ProcessError(err, offendingObject, reply);
  479.         }
  480.         
  481. //    insertHereToken.DisposeToken();
  482.     insertionLocation.Dispose();
  483.     initialData.Dispose();
  484.     initialProperties.Dispose();
  485.     resultList.Dispose();
  486.     offendingObject.Dispose();
  487.     
  488.     return err;
  489.     } // TCoreSuite::DoNewElement 
  490.  
  491. //----------------------------------------------------------------------------------------
  492. // TCoreSuite::DoNumberOfElements: 
  493. //----------------------------------------------------------------------------------------
  494. pascal OSErr TCoreSuite::DoNumberOfElements(TAEvent& ae, TAEvent& reply, long /* refCon */)
  495.     {
  496.     OSErr err = noErr;
  497.  
  498.     TDescriptor objectSpecifierList;
  499.     TTokenDescriptor directObjectToken;
  500.     TDescriptor result;
  501.     TDescriptor offendingObject;
  502.     TAETransaction transaction(ae, reply);
  503.     NOREGISTER(transaction);
  504.     
  505.     long theCount = 0;
  506.     
  507.     Try
  508.         {
  509.         TTransactionSuite::BeginEventTransaction(transaction, kTransactionNotRequired);
  510.         objectSpecifierList = ae.GetDescriptorParameter(keyDirectObject);
  511.         directObjectToken = objectSpecifierList.Resolve(transaction);
  512.         
  513.         //
  514.         // Get the type of object to count.  If no type was
  515.         // specified, assume typeWildCard.
  516.         //
  517.         DescType classToCount = ae.GetDescTypeParameter(keyAEObjectClass);
  518.         if(!classToCount)
  519.             classToCount = typeWildCard;
  520.  
  521.         TAbstractScriptableObject* token = directObjectToken.TokenObject();
  522.             {
  523.             theCount += token->CountElements(transaction, classToCount);
  524.             }
  525.         
  526.         TTransactionSuite::EndEventTransaction(transaction);
  527.         result.SetSInt32Data(theCount);
  528.         reply.PutResult(result);
  529.         }
  530.     Catch(err)
  531.         {
  532.         TTransactionSuite::TerminateEventTransaction(transaction);
  533.         ProcessError(err, offendingObject, reply);
  534.         }
  535.  
  536.     result.Dispose();
  537.     directObjectToken.DisposeToken();
  538.     objectSpecifierList.Dispose();
  539.     offendingObject.Dispose();
  540.     
  541.     return err;
  542.     } // TCoreSuite::DoNumberOfElements 
  543.  
  544. //----------------------------------------------------------------------------------------
  545. // TCoreSuite::DoCommand: 
  546. //----------------------------------------------------------------------------------------
  547. pascal OSErr TCoreSuite::DoCommand(TAEvent& ae, TAEvent& reply, long refCon)
  548.     {
  549.     OSErr err = noErr;
  550.     
  551.     TDescriptor objectSpecifierList;
  552.     TTokenDescriptor directObjectToken;
  553.     TDescriptor resultList;
  554.     TDescriptor noOptionalParameters;
  555.     TDescriptor resultDescriptor;
  556.     TDescriptor offendingObject;
  557.     TAETransaction transaction(ae, reply);
  558.     NOREGISTER(transaction);
  559.  
  560.     Try
  561.         {
  562.         TTransactionSuite::BeginEventTransaction(transaction);;
  563.         objectSpecifierList = ae.GetOptionalParameter(keyDirectObject);
  564.         directObjectToken = objectSpecifierList.Resolve(transaction, &offendingObject);
  565.         
  566.         TAbstractScriptableObject* token = directObjectToken.TokenObject();
  567.             {
  568.             resultDescriptor = token->AECommandDispatch(transaction, refCon);
  569.             resultList.AppendListAndDispose(resultDescriptor);
  570.             resultDescriptor.ClearDescriptor();
  571.             }
  572.         TTransactionSuite::EndEventTransaction(transaction);
  573.         reply.PutResult(resultList);
  574.         }
  575.     Catch(err)
  576.         {
  577.         TTransactionSuite::TerminateEventTransaction(transaction);
  578.         resultDescriptor.Dispose();
  579.         ProcessError(err, offendingObject, reply);
  580.         }
  581.     
  582.     objectSpecifierList.Dispose();
  583.     directObjectToken.DisposeToken();
  584.     resultList.Dispose();
  585.     offendingObject.Dispose();
  586.     
  587.     return err;
  588.     } // TCoreSuite::DoCommand 
  589.  
  590. //----------------------------------------------------------------------------------------
  591. // TCoreSuite::DoOpen: 
  592. //----------------------------------------------------------------------------------------
  593. pascal OSErr TCoreSuite::DoOpen(TAEvent& ae, TAEvent& reply, long refCon)
  594.     {
  595.     OSErr err = noErr;
  596.     
  597.     TDescriptor objectSpecifierList;
  598.     TTokenDescriptor directObjectToken;
  599.     TDescriptor resultList;
  600.     TDescriptor noOptionalParameters;
  601.     TTokenDescriptor appToOpenWith;
  602.     TDescriptor resultDescriptor;
  603.     TDescriptor offendingObject;
  604.     TAETransaction transaction(ae, reply);
  605.     NOREGISTER(transaction);
  606.  
  607.     Try
  608.         {
  609.         objectSpecifierList = ae.GetDescriptorParameter(keyDirectObject);
  610.         
  611.         TTransactionSuite::BeginEventTransaction(transaction);;
  612.         
  613.         //
  614.         // It's legal to say "open alias..." (in fact, common).
  615.         // In that case, send the open straight to the null container.
  616.         //
  617.         // Per convention, though, the Finder always sends a list
  618.         // of alias or FSSpec descriptors, even if only one item
  619.         // was opened.
  620.         //
  621.         if((objectSpecifierList.DescriptorType() == typeAlias) || (objectSpecifierList.DescriptorType() == typeFSS) || (objectSpecifierList.DescriptorType() == typeAEList))
  622.             {
  623.             directObjectToken = CreateNullContainerToken();
  624.             TAbstractScriptableObject* token = directObjectToken.TokenObject();
  625.             resultList = token->AECommand(transaction, refCon);
  626.             }
  627.         //
  628.         // If the direct object isn't an alias/fsspec
  629.         // then resolve and process it as usual
  630.         //
  631.         else
  632.             {
  633.             directObjectToken = objectSpecifierList.Resolve(transaction, &offendingObject);
  634.             TAbstractScriptableObject* token = directObjectToken.TokenObject();
  635.                 {
  636.                 resultDescriptor = token->AECommand(transaction, refCon);
  637.                 resultList.AppendListAndDispose(resultDescriptor);
  638.                 resultDescriptor.ClearDescriptor();
  639.                 }
  640.             }
  641.         
  642.         TTransactionSuite::EndEventTransaction(transaction);
  643.         reply.PutResult(resultList);
  644.         }
  645.     Catch(err)
  646.         {
  647.         TTransactionSuite::TerminateEventTransaction(transaction);
  648.         resultDescriptor.Dispose();
  649.         ProcessError(err, offendingObject, reply);
  650.         }
  651.  
  652.     objectSpecifierList.Dispose();
  653.     directObjectToken.DisposeToken();
  654.     resultList.Dispose();
  655.     appToOpenWith.DisposeToken();
  656.     offendingObject.Dispose();
  657.     
  658.     return err;
  659.     } // TCoreSuite::DoOpen 
  660.  
  661. #if 0
  662.  
  663. //
  664. // A more generic version of 'DoOpen,' for applications that can resolve
  665. // every object specifier that the Finder can:
  666. //
  667.  
  668. //----------------------------------------------------------------------------------------
  669. // TCoreSuite::DoOpen: 
  670. //----------------------------------------------------------------------------------------
  671. pascal OSErr TCoreSuite::DoOpen(TAEvent& ae, TAEvent& reply, long refCon)
  672.     {
  673.     OSErr err = noErr;
  674.     
  675.     TDescriptor objectSpecifierList;
  676.     TTokenDescriptor directObjectToken;
  677.     TDescriptor resultList;
  678.     TDescriptor noOptionalParameters;
  679.     TDescriptor openUsing;
  680.     TTokenDescriptor appToOpenWith;
  681.     TDescriptor resultDescriptor;
  682.     TAETransaction transaction(ae, reply);
  683.     NOREGISTER(transaction);
  684.     
  685.     Try
  686.         {
  687.         TTransactionSuite::BeginEventTransaction(transaction);;
  688.         objectSpecifierList = ae.GetDescriptorParameter(keyDirectObject);
  689.         directObjectToken = objectSpecifierList.Resolve(transaction);
  690.         openUsing = ae.GetOptionalParameter(keyAEUsing);
  691.         
  692.         //
  693.         // If there is an 'open using' parameter, then send the
  694.         // open command to it; the optional parameter is the
  695.         // list of documents to open
  696.         //
  697.         if(openUsing.DescriptorType() != typeNull)
  698.             {
  699.             appToOpenWith = openUsing.Resolve(transaction, &offendingObject);
  700.             
  701.             TAbstractScriptableObject* token = appToOpenWith.TokenObject();
  702.                 {                
  703.                 resultDescriptor = token->AECommand(transaction, ae, reply, refCon, directObjectToken.TokenObject());
  704.                 resultList.AppendListAndDispose(resultDescriptor);
  705.                 resultDescriptor.ClearDescriptor();
  706.                 }
  707.             }
  708.         //
  709.         // If there is no 'open using' parameter, then this
  710.         // command behaves just like "::DoCommand"
  711.         //
  712.         else
  713.             {
  714.             TAbstractScriptableObject* token = directObjectToken.TokenObject();
  715.                 {
  716.                 resultDescriptor = token->AECommand(transaction, ae, reply, refCon);
  717.                 resultList.AppendListAndDispose(resultDescriptor);
  718.                 resultDescriptor.ClearDescriptor();
  719.                 }
  720.             }
  721.         TTransactionSuite::EndEventTransaction(transaction);
  722.         reply.PutResult(resultList);
  723.         }
  724.     Catch(err)
  725.         {
  726.         TTransactionSuite::TerminateEventTransaction(transaction);
  727.         resultDescriptor.Dispose();
  728.         ProcessError(err, offendingObject, reply);
  729.         }
  730.     
  731.     objectSpecifierList.Dispose();
  732.     directObjectToken.DisposeToken();
  733.     resultList.Dispose();
  734.     openUsing.Dispose();
  735.     appToOpenWith.DisposeToken();
  736.     
  737.     return err;
  738.     } // TCoreSuite::DoOpen 
  739.  
  740. #endif
  741.  
  742. //----------------------------------------------------------------------------------------
  743. // TCoreSuite::DoMove: 
  744. //----------------------------------------------------------------------------------------
  745. pascal OSErr TCoreSuite::DoMove(TAEvent& ae, TAEvent& reply, long refCon)
  746.     {
  747.     OSErr err = noErr;
  748.     
  749.     TDescriptor objectSpecifierList;
  750.     TTokenDescriptor directObjectToken;
  751.     TDescriptor resultList;
  752.     TDescriptor noOptionalParameters;
  753.     TDescriptor destinationObjectSpecifier;
  754.     TDescriptor insertionLocation;
  755.     TTokenDescriptor destinationObjectToken;
  756.     TDescriptor resultDescriptor;
  757.     TDescriptor offendingObject;
  758.     TAETransaction transaction(ae, reply);
  759.     NOREGISTER(transaction);
  760.     
  761.     Try
  762.         {
  763.         TTransactionSuite::BeginEventTransaction(transaction);;
  764.         objectSpecifierList = ae.GetDescriptorParameter(keyDirectObject);
  765.         directObjectToken = objectSpecifierList.Resolve(transaction, &offendingObject);
  766.         insertionLocation = ae.GetOptionalParameter(keyAEInsertHere);
  767.         
  768.         if(insertionLocation.IsNullDescriptor() && (refCon == kAEClone))
  769.             {
  770.             TAbstractScriptableObject* token = directObjectToken.TokenObject();
  771.                 {
  772.                 resultDescriptor = token->AECommandDispatch(transaction, kAEDuplicate);
  773.                 resultList.AppendListAndDispose(resultDescriptor);
  774.                 resultDescriptor.ClearDescriptor();
  775.                 }
  776.             }
  777.         else
  778.             {
  779.             //
  780.             // the keyAEInsertHere could be either an object specifier or
  781.             // a typeInsertionLoc (which contains an object specifier and
  782.             // an enumerated position--before, after, etc.).  There is no
  783.             // automatic conversion between a typeInsertionLoc and Object
  784.             // specifiers, so we must be prepared to accept either.
  785.             //
  786.             if(insertionLocation.DescriptorType() != typeObjectSpecifier)
  787.                 {
  788.                 //
  789.                 // At this point we are assuming that the object
  790.                 // stored in 'keyAEInsertHere' is of type typeInsertionLoc.
  791.                 // If it isn't, then the call to 'GetDescriptorParameter' will fail.
  792.                 //
  793.                 destinationObjectSpecifier = insertionLocation.GetDescriptorParameter(keyAEObject,typeObjectSpecifier);
  794.                 insertionLocation.Dispose();
  795.                 }
  796.             //
  797.             // If keyAEInsert here is not a typeInsertionLoc, then just
  798.             // have the destination object specifier adopt it
  799.             //
  800.             else
  801.                 {
  802.                 destinationObjectSpecifier.AdoptDescriptor(insertionLocation);
  803.                 insertionLocation.ClearDescriptor();
  804.                 }
  805.             destinationObjectToken = destinationObjectSpecifier.Resolve(transaction, &offendingObject);
  806.             
  807.             //
  808.             // In reality, our code will flail and fail if there is more than one
  809.             // destination for a move (since the source will no longer exist by
  810.             // the time that the second destination gets the event).  It is
  811.             // legal to have multiple destinations for a copy, though, so we'll
  812.             // leave the loop here and just allow multiple moves to fail naturally.
  813.             //
  814.             TAbstractScriptableObject* token = destinationObjectToken.TokenObject();
  815.                 {
  816.                 resultDescriptor = token->AECommand(transaction, refCon, directObjectToken.TokenObject());
  817.                 resultList.AppendListAndDispose(resultDescriptor);
  818.                 resultDescriptor.ClearDescriptor();
  819.                 }
  820.             }
  821.         TTransactionSuite::EndEventTransaction(transaction);
  822.         reply.PutResult(resultList);
  823.         }
  824.     Catch(err)
  825.         {
  826.         TTransactionSuite::TerminateEventTransaction(transaction);
  827.         resultDescriptor.ClearDescriptor();
  828.         ProcessError(err, offendingObject, reply);
  829.         }
  830.     
  831.     objectSpecifierList.Dispose();
  832.     directObjectToken.DisposeToken();
  833.     resultList.Dispose();
  834.     insertionLocation.Dispose();
  835.     destinationObjectSpecifier.Dispose();
  836.     destinationObjectToken.DisposeToken();
  837.     offendingObject.Dispose();
  838.     
  839.     return err;    
  840.     } // TCoreSuite::DoMove 
  841.